#ifndef __VERTEXBUFFERLAYOUT_H__
#define __VERTEXBUFFERLAYOUT_H__

#include <vector>
#include "GL/glew.h"

struct VertexBufferLayoutElement
{
	unsigned int Type;
	unsigned int Count;
	unsigned char Normalize;

	static unsigned int GetSizeOfType(unsigned int Type) {
		switch (Type)
		{
			case GL_FLOAT:			return 4;
			case GL_UNSIGNED_INT:	return 4;
			case GL_UNSIGNED_BYTE:	return 1;
		}

		return 0;
	}
};

class VertexBufferLayout {
private:
	std::vector<VertexBufferLayoutElement> Elements;
	unsigned int Stride;

public:
	VertexBufferLayout() 
		: Stride(0)
	{
	}

	~VertexBufferLayout() 
	{
	}

public:
	template<typename T>
	void Push(unsigned int count) {
		static_assert();
	}

	template<>
	void Push<float>(unsigned int count) {
		Elements.push_back(
			{
				GL_FLOAT,
				count,
				GL_FALSE
			}
		);

		Stride += count * VertexBufferLayoutElement::GetSizeOfType(GL_FLOAT);
	}

	template<>
	void Push<unsigned int>(unsigned int count) {
		Elements.push_back(
			{
				GL_UNSIGNED_INT,
				count,
				GL_FALSE
			}
		);

		Stride += count * VertexBufferLayoutElement::GetSizeOfType(GL_UNSIGNED_INT);
	}

	template<>
	void Push<unsigned char>(unsigned int count) {
		Elements.push_back(
			{
				GL_UNSIGNED_BYTE,
				count,
				GL_FALSE
			}
		);

		Stride += count * VertexBufferLayoutElement::GetSizeOfType(GL_UNSIGNED_BYTE);
	}

public:
	inline const std::vector<VertexBufferLayoutElement>& GetElements() const {
		return Elements;
	}

	inline unsigned int GetStride() const {
		return Stride;
	}
};

#endif // !__VERTEXBUFFERLAYOUT_H__
